package com.wtwd.campus.service.impl;

import com.wtwd.campus.entity.LbsData;
import com.wtwd.campus.entity.LocationInfo;
import com.wtwd.campus.entity.WifiData;
import com.wtwd.campus.model.dto.LbsDTO;
import com.wtwd.campus.model.dto.WifiDTO;
import com.wtwd.campus.service.LbsDataService;
import com.wtwd.campus.service.OrientationCacheService;
import com.wtwd.campus.service.WifiDataService;
import com.wtwd.campus.utils.GPSUtils;
import com.wtwd.campus.utils.Vizhi.entity.Cellular;
import com.wtwd.campus.utils.Vizhi.entity.Wifi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class OrientationCacheServiceImpl implements OrientationCacheService {

    private static final Logger log = LoggerFactory.getLogger(OrientationCacheServiceImpl.class);

    @Resource
    private LbsDataService lbsDataService;

    @Resource
    private WifiDataService wifiDataService;


    @Override
    public LocationInfo getLocation(String deviceNo, List<LbsDTO> lbs, List<WifiDTO> wifis) {
        LocationInfo locationByWifi = null;
        LocationInfo locationByLBS = null;
        if (wifis != null&&wifis.size()>0) {//获取wifi定位
            locationByWifi = wifiDataService.getLocationByWifi(wifis);
        }
        if (lbs != null&&lbs.size()>0) {//获取基站信息定位
            locationByLBS = lbsDataService.getLocationByLBS(lbs);
        }
        if (locationByWifi != null && locationByLBS != null) {//采用基站wifi联合定位的方式
            LocationInfo wifi = processingHitWifi(wifis, locationByWifi);
            if (wifi != null) {
                //如果wifi命中--则对比基站 wifi 间距(如果间距小于一定距离则命中缓存)
                double distance = GPSUtils.getDistance(wifi.getLng(), wifi.getLat(), locationByLBS.getLng(), locationByLBS.getLat());
                if (distance < LBS_WIFI_DISTANCE) {
                    return wifi;
                }
            }
        } else if (locationByLBS != null) {
            return locationByLBS;
        } else if (locationByWifi != null) {//处理wifi定位
            return processingHitWifi(wifis, locationByWifi);
        }
        return null;
    }

    @Override
    public LocationInfo processingHitWifi(List<WifiDTO> wifis, LocationInfo locationByWifi) {
        if (wifis == null || wifis.size() == 0 || locationByWifi == null) {
            return null;
        }
        /**
         * 1.如果上传wifi的数量大于等于5个则，命中wifi数量过半则命中缓存
         * 否则上传的wifi数量小于5个则必须命中3个及其以上才命中缓存
         */
        int matchedMacNum = locationByWifi.getMatchedMacNum();
        if (wifis.size() >= 5) {
            if (matchedMacNum * 2 > wifis.size()) {//如果命中wifi的数量大于一半则命中缓存
                return locationByWifi;
            }
        } else {
            if (matchedMacNum >= 3) {
                return locationByWifi;
            }
        }
        return null;
    }

    @Override
    public LocationInfo getCacheLocation(String imei, List<Wifi> wifiList, List<Cellular> cellulars) {
        List<LbsDTO> lbsDTOS = new ArrayList<>();
        List<WifiDTO> wifiDTOS = new ArrayList<>();
        if (wifiList != null && wifiList.size() > 0) {
            for (Wifi wifi : wifiList) {
                WifiDTO wifiDTO = new WifiDTO();
                wifiDTO.setMac(wifi.getMacAddress());
                wifiDTO.setSignal(wifi.getSignalStrength());
                wifiDTOS.add(wifiDTO);
            }
        }
        if (cellulars != null && cellulars.size() > 0) {
            for (Cellular cellular : cellulars) {
                LbsDTO lbsDTO = new LbsDTO();
                lbsDTO.setMcc(cellular.getMobileCountryCode());
                lbsDTO.setMnc(cellular.getMobileNetworkCode());
                lbsDTO.setRadioType(cellular.getRadioType());
                lbsDTO.setCid(Long.valueOf(cellular.getCellId()));
                lbsDTO.setLac(cellular.getLocationAreaCode());
                lbsDTO.setSignal(cellular.getSignalStrength());
                lbsDTOS.add(lbsDTO);
            }
        }
        return getLocation(imei, lbsDTOS, wifiDTOS);
    }

    @Override
    public boolean saveCacheLocation(List<Cellular> cellulars, List<Wifi> wifiList, String imei, double longitude, double latitude, String dataSourceType, float accuracy, String address) {
        ArrayList<WifiData> wifiDatas = new ArrayList<>();
        ArrayList<LbsData> lbsDatas = new ArrayList<>();
        if (cellulars != null && cellulars.size() > 0) {
            for (Cellular cellular : cellulars) {
                LbsData lbsData = new LbsData();
                lbsData.setRadio(cellular.getRadioType());
                lbsData.setMcc(cellular.getMobileCountryCode());
                lbsData.setMnc(cellular.getMobileNetworkCode());
                lbsData.setLac(cellular.getLocationAreaCode());
                lbsData.setCid(Long.valueOf(cellular.getCellId()));
                lbsData.setLng(longitude);
                lbsData.setLat(latitude);
                lbsData.setChangeable(Integer.valueOf(dataSourceType));
                lbsData.setCreateTime(new Date());
                lbsData.setUpdateTime(new Date());
                lbsData.setAddress(address);
                lbsDatas.add(lbsData);
            }
        }
        if (wifiList != null && wifiList.size() > 0) {
            for (Wifi wifi : wifiList) {
                WifiData wifiData = new WifiData();
                wifiData.setMac(wifi.getMacAddress());
                wifiData.setSignalValue(wifi.getSignalStrength());
                wifiData.setLng(longitude);
                wifiData.setLat(latitude);
                wifiData.setAccuracy(String.valueOf(accuracy));
                wifiData.setDeviceNo(imei);
                wifiData.setDataSource(dataSourceType);
                wifiData.setDataState(accuracy > POSITIONING_ACCURACY ? "0" : "1");
                wifiData.setCreateTime(new Date());
                wifiData.setUpdateTime(new Date());
                wifiData.setAddress(address);
                wifiDatas.add(wifiData);
            }
        }
        if (wifiDatas != null && wifiDatas.size() > 0) {//批量插入或者更新wifi数据
            wifiDataService.batchInsertOrUpdate(wifiDatas);
        }
        if (lbsDatas != null && lbsDatas.size() > 0) {//批量插入或者更新lbs数据
            lbsDataService.batchInsertOrUpdate(lbsDatas);
        }
        return true;
    }


}
